package FileManager;

import java.util.Arrays;

import DiskManager.Disk;
import DiskManager.DiskBit;

public class SimulationFile extends SimulateContent{
        String content="";
        char[]   ContentArrary=new char[1];
        public SimulationFile() {setName("");}
     	public SimulationFile(String name,String ExtendName,String attribute,int starnum,SimulationDirectory father,Disk disk) {
		setName(name);
		setExtendName(ExtendName);
		setattribute(attribute);
		setstranum(starnum);
		 setSize(16);
		this.father = father;
		this.father.addChildren(this);
                                           	}
     	public SimulationFile(String name,String ExtendName,String attribute,int starnum,SimulationDirectory father,int size,Disk disk) {
    		setName(name);
    		setExtendName(ExtendName);
    		setattribute(attribute);
    		setstranum(starnum);
    		 setSize(size);
    		this.father = father;
    		this.father.addChildren(this);
                                               	}
     	public SimulationFile(String name,String ExtendName,String attribute) {
    		setName(name);
    		setExtendName(ExtendName);
    		setattribute(attribute);
    		
                                               	}
        public SimulationDirectory getFather()
        {
        	return (SimulationDirectory)father;
        }
        
        private char[] setSaveContentArrary() {
        	String sname = String.format("%6s",new String(this.name)); 
        	String sextendname = String.format("%2s",new String(this.ExtendName));
        	String sattribute = String.format("%1s",new String(this.attribute));
        	String sstartnum = String.format("%3s",new String(this.startnum));
        	String ssize = String.format("%4s",new String(this.size));
        	String all = new String();
        	all=sname+sextendname+sattribute+sstartnum+ssize;
        	all+=this.content;
        	all=all.replaceAll("\n|\t", "¿");
        	char[] allContent = all.toCharArray();
        	return allContent;
    	}

    	public int getSizeNumber() {
    		if(this.content.equals("")) {
    			return 16;
    		}
    		return ContentArrary.length + 16;
    	}

    	public void saveContentArrary(Disk disk) {
    		this.changeSize(this,this.getSizeNumber()-this.getSize());
    		char[] allSaveContent = this.setSaveContentArrary();
    		int restsize = this.getSizeNumber();
    		int times = restsize / 128;
    		if (restsize % 128 != 0)
    			times++;
    		System.out.println(Arrays.toString(allSaveContent));
    		if(!this.judgeRestROM(times-1, disk)) {// 判断空间
    			System.out.println("not enough space");
    			return;
    		}

    		this.creatNextFAT(times-1, disk);// 根据次数分配FAT
    		
    		int diskblock = this.getStartnum();
    		char[] savecontent = new char[128];
    		for (int i = 0; i < times; i++) {
    			if (restsize <= 128) {
    				System.arraycopy(allSaveContent, i * 128, savecontent, 0, restsize);
    				for(int j=restsize;j<128;j++)savecontent[j]=' ';
    				disk.save(diskblock, savecontent);
    				
    				diskblock = this.getNextDiskBlock(diskblock, disk);// 获取下一块diskblock

    			} else {
    				System.arraycopy(allSaveContent, i * 128, savecontent, 0, 128);
    				disk.save(diskblock, savecontent);

    				restsize-=128;
    				diskblock = this.getNextDiskBlock(diskblock, disk);// 获取下一块diskblock
    			}
    		}
    		System.out.println("保存成功");
    	}

    	public void initialize(Disk disk) {
    		int Num = this.getStartnum();
    		String openString = "";
    		while (Num != -1) {
    			DiskBit diskbit = disk.getDiskBit()[Num];
    			char[] openContent = diskbit.load();
    			String gd = new String(openContent);
    			openString+=gd;

    			Num = this.getNextDiskBlock(Num, disk);// 获取下一块diskblock

    		}
    		openString = openString.substring(16,this.getSize()).replaceAll("¿", "\n");
    		this.setContent(openString);
    	} 
    	
    	private boolean judgeRestROM(int ROMneed,Disk disk) {
    		int fileStartNum = this.getStartnum();
    		char directory = judgeDirectory(fileStartNum);
    		int restROM = countRestROM(directory,disk);
    		if(ROMneed<=restROM)return true;
    		return false;
    	}
    	
    	private void creatNextFAT(int times,Disk disk) {
    		int[] smallfat;
    		char directory = judgeDirectory(this.getStartnum());
    		smallfat = this.creatFATArray(directory, disk, times);
    		int FATPosition = this.getStartnum();
    		int[] FAT = disk.getFAT();
    		for(int i=0;i<smallfat.length;i++) {
    			FAT[FATPosition] = smallfat[i];
    			FATPosition = smallfat[i];
    		}
    		FAT[FATPosition] = -1;
    	}
    	
    	
    	
    	private int getNextDiskBlock(int num,Disk disk) {
    		int[] FAT = disk.getFAT();
    		return FAT[num];
    	}
    	
    	
    	
    	private int countRestROM(char directory,Disk disk) {
    		int start = 4;
    		int end = 62;
    		int count = 0;
    		switch(directory){
    		case('C'):break;
    		case('D'):start += 60;end += 60;break;
    		case('E'):start +=120;end += 120;break;
    		case('F'):start +=180;end += 180;break;
    		}
    		int[] fat = disk.getFAT();
    		for (int i=start;i<=end;i++) {
    			if(fat[i]==0)count++;
    		}
    		return count;
    	}
    	
    	private int[] creatFATArray(char directory,Disk disk,int num) {
    		int[] smallFAT = new int[num];
    		int start = 4;
    		int end = 62;
    		int count = 0;
    		switch(directory){
    		case('C'):break;
    		case('D'):start += 60;end += 60;break;
    		case('E'):start +=120;end += 120;break;
    		case('F'):start +=180;end += 180;break;
    		}
    		int[] fat = disk.getFAT();
    		int smallFATPosition = 0;
    		for (int i=start;i<=end;i++) {
    			if(fat[i]==0) {
    				smallFAT[smallFATPosition] = i;
    				smallFATPosition++;
    			}
    			if(smallFATPosition==num)return smallFAT;
    		}
    		System.out.println("creatFATArray_ERROR");
    		return null; 
    	}
    	//
    	public String getContent() {
			return  new String(ContentArrary);
		}
		public void setContent(String content) {
			this.content = content;
			ContentArrary = content.toCharArray();
		}
		public char[] getContentArrary() {
			return ContentArrary;
		}
    	
}
